package com.tcs.teg.domain.accounts;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;


import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.Version;

/**
 * This class is used to set the value for common persistence entities.
 * 
 * @Modified on Jun 21,2011 PP75206 , Added Comment.
 * 
 */
@MappedSuperclass
public abstract class BasicEntity implements Serializable {

	private static final long serialVersionUID = -4915214494836487663L;

	@Transient
	private static final ThreadLocal<String> CURRENT_USER = new ThreadLocal<String>();

	@Transient
	private static final ThreadLocal<String> CURRENT_USER_NAMESPACE = new ThreadLocal<String>();

	@Column(name = "update_user")
	private String updateUser;

	@Column(name = "update_user_namespace")
	private String updateUserNamespace;

	@Version
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "update_datetime")
	private Date updateDateTime;

	@Column(name = "insert_user")
	private String insertUser;

	@Column(name = "insert_user_namespace")
	private String insertUserNamespace;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "insert_datetime")
	private Date insertDateTime;

	/**
	 * This method is used to set the value to be used for the insert & update
	 * users
	 * 
	 * @param user
	 */

	public static void setCurrentUser(String user) {
		CURRENT_USER.set(user);
	}

	/**
	 * This method is used to set the value to be used for the insert & update
	 * user namespace
	 * 
	 * @param user
	 */

	public static void setCurrentUserNamespace(String userNamespace) {
		CURRENT_USER_NAMESPACE.set(userNamespace);
	}

	public abstract Long getId();

	public abstract void setId(Long id);

	public Date getInsertDateTime() {
		return insertDateTime;
	}

	public void setInsertDateTime(Date insertDateTime) {
		this.insertDateTime = insertDateTime;
	}

	public String getInsertUser() {
		return insertUser;
	}

	public void setInsertUser(String insertUser) {
		this.insertUser = insertUser;
	}

	public String getInsertUserNamespace() {
		return insertUserNamespace;
	}

	public void setInsertUserNamespace(String insertUserNamespace) {
		this.insertUserNamespace = insertUserNamespace;
	}

	public Date getUpdateDateTime() {
		return updateDateTime;
	}

	public void setUpdateDateTime(Date updateDateTime) {
		this.updateDateTime = updateDateTime;
	}

	public String getUpdateUser() {
		return updateUser;
	}

	public void setUpdateUser(String updateUser) {
		this.updateUser = updateUser;
	}

	public String getUpdateUserNamespace() {
		return updateUserNamespace;
	}

	public void setUpdateUserNamespace(String updateUserNamespace) {
		this.updateUserNamespace = updateUserNamespace;
	}

	/*
	 * This method is used to set the value to be used for the insertUser ,
	 * insertUserNamespace& insertDateTime
	 */
	//@PrePersist
	public void setInsertValues() {

		if (CURRENT_USER.get() != null) {
			setInsertDateTime(new Timestamp(new Date().getTime()));
			setInsertUser(CURRENT_USER.get());
			setInsertUserNamespace(CURRENT_USER_NAMESPACE.get());
		} else {
			setInsertDateTime(new Timestamp(new Date().getTime()));
			setInsertUser("TESTUSER");
			setInsertUserNamespace("DEFAULT");
		}
		setUpdateValues();
	}

	/*
	 * JPA way of doing the same thing what we have achieved in hibernate interceptor and events.
	 * This method is used to set the value to be used for the updateUser and
	 * updateUserNamespace.
	 */
	//@PreUpdate
	public void setUpdateValues() {
		// Don't set update time - the versioning in JPA will handle that
		if (CURRENT_USER.get() != null) {
			setUpdateUser(CURRENT_USER.get());
			setUpdateUserNamespace(CURRENT_USER_NAMESPACE.get());
		} else {
			setUpdateUser("TESTUSER");
			setUpdateUserNamespace("DEFAULT");
		}
	}

	@Override
	public boolean equals(Object arg0) {

		if (arg0 == null || !(arg0 instanceof BasicEntity))
			return false;
		if (((BasicEntity) arg0).getId() == this.getId() || this == arg0)
			return true;

		return false;
	}
	
}
